package com.hwg.shiliupro.service.Impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hwg.shiliupro.dao.HomePageMapper;
import com.hwg.shiliupro.dao.UserMapper;
import com.hwg.shiliupro.dao.WorkMapper;
import com.hwg.shiliupro.dto.LoginDto;
import com.hwg.shiliupro.dto.PageBean;
import com.hwg.shiliupro.dto.ScoreDto;
import com.hwg.shiliupro.dto.UserQueryDto;
import com.hwg.shiliupro.finals.Code;
import com.hwg.shiliupro.po.HomePage;
import com.hwg.shiliupro.po.R;
import com.hwg.shiliupro.po.User;
import com.hwg.shiliupro.po.Work;
import com.hwg.shiliupro.service.UserService;
import com.hwg.shiliupro.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private WorkMapper workMapper;

    @Autowired
    private HomePageMapper homePageMapper;

    /**
     * 登录
     *
     * @param loginDto 登录dto
     * @return {@link User}
     */
    @Override
    public User login(LoginDto loginDto) {
        try {
            loginDto.setPassword(Md5Util.encodeByMd5(loginDto.getPassword()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return userMapper.login(loginDto);
    }

    /**
     * 分页and条件查询
     *
     * @param userQueryDto 用户查询dto
     * @return {@link PageBean}<{@link User}>
     */
    @Override
    public PageBean<User> selectByPageAndCondition(UserQueryDto userQueryDto) {
        //起始索引beginIndex=（当前页码-1）×每页显示记录数目
        int beginIndex = (userQueryDto.getPage() - 1) * userQueryDto.getSize();
        String number = null;
        String name = null;
        if(userQueryDto.getNumber()!=null && !userQueryDto.getNumber().equals("") ){
            number = "%"+userQueryDto.getNumber()+"%";
        }
        if(userQueryDto.getName()!=null && !userQueryDto.getName().equals("") ) {
            name = "%"+userQueryDto.getName()+"%";
        }
        List<User> users = userMapper.selectByPageAndCondition(beginIndex, userQueryDto.getSize(),
                number, name, userQueryDto.getSgroup(), userQueryDto.getOrder());
        int count = userMapper.selectCount();
        PageBean<User> userPageBean =  new PageBean<>(count,users);
        return userPageBean;
    }

    /**
     * 新增用户
     *
     * @param user 用户
     * @return {@link Boolean}
     */
    @Override
    public Boolean insertUser(User user) {
        int count = userMapper.insertUser(user);
        HomePage homePage = HomePageUtil.getHomePage(user);
        homePageMapper.insert(homePage);
        return count > 0;
    }

    /**
     * 删除通过id
     *
     * @param id id
     */
    @Override
    public Boolean deleteById(Integer id) {
        int count = userMapper.deleteById(id);
        homePageMapper.deleteById(id);
        return count > 0;
    }

    /**
     * 更新用户
     *
     * @param user 用户
     * @return {@link Boolean}
     */
    @Override
    public Boolean updateUser(User user) {
        try {
            user.setPassword(Md5Util.encodeByMd5(user.getPassword()));
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        int count = userMapper.updateById(user);
        HomePage homePage = HomePageUtil.getHomePage(user);
        QueryWrapper<HomePage> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status",Code.EXAMINE_OK);
        homePageMapper.update(homePage,queryWrapper);
        return count > 0;
    }

    /**
     * 通过邮件查找学生
     *
     * @param mail 邮件
     * @return {@link User}
     */
    @Override
    public User selectByMail(String mail) {
        User user = userMapper.selectByMail(mail);
        return user;
    }

    /**
     * 发送邮件
     *
     * @param user 用户
     * @return {@link Boolean}
     */
    @Override
    public R sendMail(User user) {
        String uuid = UuidUtil.getUuid();
        //更新保护码
        if(!userMapper.updateProtectCode(user.getId(), uuid)){
            return R.error().code(Code.GET_ERR).message("请稍后再试");
        }
        String content = "<a href='http://localhost:8080/api/users/updatePasswordByMail?number="+user.getNumber()+"&protectCode="+uuid+"'>点击这里重置密码</a>" +
                "密码将重置为您的学号+如下四个字符:"+uuid.substring(28);
        boolean flag = MailUtils.sendMail(user.getMail(), content,"重置密码");
        log.info("用户将访问的地址是：{}",content);
        log.info("是否成功发送邮件：{}",flag);
        if(!flag){
            return R.error().code(Code.GET_ERR).message("请稍后再试");
        }
        return R.ok().code(Code.GET_OK);
    }

    /**
     * 重置密码
     *
     * @param protectCode 保护代码
     * @param newPassword 新密码
     * @return {@link Boolean}
     */
    @Override
    public Boolean updatePasswordByProtectCode(String protectCode, String newPassword) {
        try {
            String password = Md5Util.encodeByMd5(newPassword);
            int i = userMapper.updatePasswordByprotectCode(protectCode, password);
            return i > 0;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 通过id查找用户
     *
     * @param id id
     * @return {@link User}
     */
    @Override
    public User selectById(Integer id) {
        return userMapper.selectById(id);
    }

    /**
     * 通过id拉黑用户
     * 方案一：存储到数据库的  拉黑开始时间和拉黑结束时间都用String字符串 这样简单
     * 方案二：数据库的类型用DateTime  java这边用util.Date 然后结合Timestamp类可以把Date存到数据库
     * @param id   id
     * @param block 时间
     * @return int
     */
    @Override
    public Boolean blockById(Integer id,String block) {
        //block   2022-12-10T15:19  拉黑到期时间  需要解析 并入数据库
        try {
            //使用Util将前端传的日期转为 标准格式 yyyy-MM-dd HH:mm:ss
            String endTime = SimpleDateFormatUtil.getDateStr(block);
            Date beginTime = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String format = sdf.format(beginTime);
            System.out.println(endTime);
            System.out.println(format);
            //方案一存储字符串
            return userMapper.blockById(id,endTime,format) > 0;
            //方案二  使用timestamp
        } catch (ParseException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 解除黑名单
     *
     * @param id id
     * @return {@link Boolean}
     */
    @Override
    public Boolean freeBlock(Integer id) {
        //调用的是和拉黑同一个方法  其实是 解除
        return userMapper.blockById(id,null,null) > 0;
    }

    /**
     * 获得已拉黑用户
     *
     * @return {@link List}<{@link User}>
     */
    @Override
    public List<User> getBlocks() {
        return userMapper.getBlocks();
    }

    /**
     * 是否进入黑名单
     *
     * @param id id
     * @return boolean
     */
    @Override
    public User isBlock(Integer id) {
        return userMapper.isBlock(id);
    }

    /**
     * 获取积分榜信息
     *
     * @return {@link List}<{@link ScoreDto}>
     */
    @Override
    public List<ScoreDto> selectAllScore() {
        List<ScoreDto> list  = new ArrayList<>();
        List<User> users = userMapper.selectList(null);
        ScoreDto scoreDto = null;
        for (User user : users) {
            scoreDto = new ScoreDto();
            scoreDto.setName(user.getName());
            //查询该用户审核通过了多少任务
            QueryWrapper<Work> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("u_id",user.getId());
            queryWrapper.eq("check_status",1);  //check_status为1 代表已审核通过
            Integer score = workMapper.selectCount(queryWrapper);
            scoreDto.setScore(score);
            list.add(scoreDto);
        }
        Collections.sort(list, new Comparator<ScoreDto>() {
            @Override
            public int compare(ScoreDto o1, ScoreDto o2) {
                return o2.getScore() - o1.getScore();   //按分数降序
            }
        });
        return list;
    }

}
